package com.plian.system.service.pm.property.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.plian.Tools.CollectionUtil;
import com.plian.Tools.StringUtil;
import com.plian.Tools.TokenUtil;
import com.plian.Tools.file.FilesUtil;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.dao.sys.file.FileDao;
import com.plian.system.dto.pm.property.PropertyFileDTO;
import com.plian.system.entity.pm.property.Property;
import com.plian.system.entity.pm.property.PropertyChange;
import com.plian.system.entity.pm.property.PropertyOut;
import com.plian.system.entity.pm.property.PropertyRecord;
import com.plian.system.service.pm.property.*;
import com.plian.system.service.sys.file.FileService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @description:
 * @author: gangan
 * @create: 2021-05-24 15:49
 */
@Service
public class PropertyFileServiceImpl implements IPropertyFileService {

    @Autowired
    private IPropertyRecordService propertyRecordService;

    @Autowired
    private FileService fileService;

    @Autowired
    private FileDao fileDao;

    @Autowired
    private IPropertyOutService propertyOutService;

    @Autowired
    private IPropertyService propertyService;

    @Autowired
    private IPropertyChangeService propertyChangeService;


    @Override
    public String check(List<PropertyFileDTO> propertyFileDTOS, String competentOrganization) {
        List<PropertyRecord> propertyRecordList = propertyRecordService.list(new QueryWrapper<PropertyRecord>().eq("competent_organization", competentOrganization));
        List<String> existIds = Optional.ofNullable(propertyRecordList).orElse(new ArrayList<>())
                .stream().map(PropertyRecord::getId).collect(Collectors.toList());
        StringBuilder message = new StringBuilder();
        for (PropertyFileDTO propertyFileDTO : propertyFileDTOS){
            String propertyId = propertyFileDTO.getPropertyId();

            if (StringUtil.isBlank(propertyId)){
                if (message.length() > 0){
                    message.append(",");
                }
                message.append("propertyId为空");
                continue;
            }
            if (!existIds.contains(propertyId)){
                if (message.length() > 0){
                    message.append(",");
                }
                message.append(propertyId + "在系统中不存在");
                continue;
            }
        }
        return message.toString();
    }

    @Override
    @Transactional(rollbackFor = RuntimeException.class)
    public boolean save(List<MultipartFile> files, List<PropertyFileDTO> propertyFileDTOS) {
        List<PageData> fileInfoList = FilesUtil.upFiles(files);
        Map<String, PageData> fileMap = fileInfoList.stream().collect(Collectors.toMap(p -> p.getString("md5"), p -> p, (p1, p2) -> p1));
        List<HashMap> fileList = new ArrayList<>();
        List<String> parentIds = new ArrayList<>();
        HashMap<String, String> extMap = FilesUtil.extMap();

        List<String> outIds = Optional.ofNullable(propertyOutService.list()).orElse(new ArrayList<>())
                .stream().map(PropertyOut::getId).collect(Collectors.toList());
        for (PropertyFileDTO propertyFileDTO : propertyFileDTOS){
            String propertyId = propertyFileDTO.getPropertyId();
            parentIds.add(propertyId);
            boolean outFlag = CollectionUtil.isNotEmpty(outIds) && outIds.contains(propertyId);
            if (CollectionUtil.isNotEmpty(propertyFileDTO.getF1())){
                if (outFlag){
                    setFilePageData(fileMap, extMap, propertyFileDTO.getF1(), fileList, propertyId, "fOut1");
                }else {
                    setFilePageData(fileMap, extMap, propertyFileDTO.getF1(), fileList, propertyId, "f1");
                }
            }

            if (CollectionUtil.isNotEmpty(propertyFileDTO.getF2())){
                if (outFlag){
                    setFilePageData(fileMap, extMap, propertyFileDTO.getF2(), fileList, propertyId, "fOut2");
                }else {
                    setFilePageData(fileMap, extMap, propertyFileDTO.getF2(), fileList, propertyId, "f2");
                }
            }

            if (CollectionUtil.isNotEmpty(propertyFileDTO.getF3())){
                if (outFlag){
                    setFilePageData(fileMap, extMap, propertyFileDTO.getF3(), fileList, propertyId, "fOut3");
                }else {
                    setFilePageData(fileMap, extMap, propertyFileDTO.getF3(), fileList, propertyId, "f3");
                }
            }

            if (CollectionUtil.isNotEmpty(propertyFileDTO.getF4())){
                if (outFlag){
                    setFilePageData(fileMap, extMap, propertyFileDTO.getF4(), fileList, propertyId, "fOut4");
                }else {
                    setFilePageData(fileMap, extMap, propertyFileDTO.getF4(), fileList, propertyId, "f4");
                }
            }

            if (CollectionUtil.isNotEmpty(propertyFileDTO.getF5())){
                if (outFlag){
                    setFilePageData(fileMap, extMap, propertyFileDTO.getF5(), fileList, propertyId, "fOut5");
                }else {
                    setFilePageData(fileMap, extMap, propertyFileDTO.getF5(), fileList, propertyId, "f5");
                }
            }

            if (CollectionUtil.isNotEmpty(propertyFileDTO.getF6())){
                if (outFlag){
                    setFilePageData(fileMap, extMap, propertyFileDTO.getF6(), fileList, propertyId, "fOut6");
                }else {
                    setFilePageData(fileMap, extMap, propertyFileDTO.getF6(), fileList, propertyId, "f6");
                }
            }

            if (CollectionUtil.isNotEmpty(propertyFileDTO.getF7())){
                if (outFlag){
                    setFilePageData(fileMap, extMap, propertyFileDTO.getF7(), fileList, propertyId, "fOut7");
                }else {
                    setFilePageData(fileMap, extMap, propertyFileDTO.getF7(), fileList, propertyId, "f7");
                }
            }

            if (CollectionUtil.isNotEmpty(propertyFileDTO.getF8())){
                if (outFlag){
                    setFilePageData(fileMap, extMap, propertyFileDTO.getF8(), fileList, propertyId, "fOut8");
                }else {
                    setFilePageData(fileMap, extMap, propertyFileDTO.getF8(), fileList, propertyId, "f8");
                }
            }

            if (CollectionUtil.isNotEmpty(propertyFileDTO.getF9())){
                if (outFlag){
                    setFilePageData(fileMap, extMap, propertyFileDTO.getF9(), fileList, propertyId, "fOut9");
                }else {
                    setFilePageData(fileMap, extMap, propertyFileDTO.getF9(), fileList, propertyId, "f9");
                }
            }


        }
        if (CollectionUtil.isNotEmpty(fileList)){
            try {
                fileDao.delByParentIds(parentIds);
                fileDao.saveAll(fileList);
            }catch (Exception e){
                return false;
            }
        }
        return true;
    }

    @Override
    public String unitCheck(List<PropertyFileDTO> propertyFileDTOS) {
        String tokenUserId = TokenUtil.getTokenUserId();
        List<Property> propertyList = propertyService.list(new LambdaQueryWrapper<Property>()
                .eq(Property::getDataSource, tokenUserId).isNotNull(Property::getDataSourceId));
        List<PropertyChange> propertyChangeList = propertyChangeService
                .list(new LambdaQueryWrapper<PropertyChange>().eq(PropertyChange::getDataSource, tokenUserId)
                        .isNotNull(PropertyChange::getDataSourceId));
        List<PropertyOut> propertyOutList = propertyOutService.list(new LambdaQueryWrapper<PropertyOut>()
                .eq(PropertyOut::getDataSource, tokenUserId).isNotNull(PropertyOut::getDataSourceId));
        List<String> existIds = new ArrayList<>();
        Map<String, String> dataSourceIdMap = new HashMap<>();
        if (CollectionUtil.isNotEmpty(propertyList)){
            existIds.addAll(propertyList.stream().map(Property::getDataSourceId).collect(Collectors.toList()));
            dataSourceIdMap.putAll(propertyList.stream().collect(Collectors.toMap(Property::getDataSourceId, Property::getId)));
        }
        if (CollectionUtil.isNotEmpty(propertyChangeList)){
            existIds.addAll(propertyChangeList.stream().map(PropertyChange::getDataSourceId).collect(Collectors.toList()));
            dataSourceIdMap.putAll(propertyChangeList.stream().collect(Collectors.toMap(PropertyChange::getDataSourceId, PropertyChange::getId)));
        }
        if (CollectionUtil.isNotEmpty(propertyOutList)){
            existIds.addAll(propertyOutList.stream().map(PropertyOut::getDataSourceId).collect(Collectors.toList()));
            dataSourceIdMap.putAll(propertyOutList.stream().collect(Collectors.toMap(PropertyOut::getDataSourceId, PropertyOut::getId)));
        }

        StringBuilder message = new StringBuilder();
        for (PropertyFileDTO propertyFileDTO : propertyFileDTOS){
            String dataSourceId = propertyFileDTO.getDataSourceId();

            if (StringUtil.isBlank(dataSourceId)){
                if (message.length() > 0){
                    message.append(",");
                }
                message.append("dataSourceId为空");
                continue;
            }
            if (!existIds.contains(dataSourceId)){
                if (message.length() > 0){
                    message.append(",");
                }
                message.append(dataSourceId + "在系统中不存在");
                continue;
            }
            propertyFileDTO.setPropertyId(dataSourceIdMap.get(dataSourceId));
        }
        return message.toString();
    }


    private void setFilePageData(Map<String, PageData> fileMap,  HashMap<String, String> extMap, List<String> md5List,
                                     List<HashMap> fileList, String propertyId, String type){
        for (String str : md5List){
            if (fileMap.containsKey(str)){
                PageData pd = fileMap.get(str);
                PageData fileInfoMap = fileService.fileToFileInfo(pd);
                fileInfoMap.put("parentId", propertyId);
                fileInfoMap.put("type", type);
                String ext = fileInfoMap.getString("ext");
                if (extMap.containsKey(ext)){
                    fileInfoMap.put("mime", extMap.get(ext));
                }
                fileList.add(fileInfoMap);
            }
        }
    }
}
